<template>
  <div>
    <canvas ref="canvas"></canvas>
  </div>
</template>

<script lang="ts">
import { defineComponent, onMounted, ref, onBeforeUnmount } from 'vue';

export default defineComponent({
  name: 'Fireworks',
  setup() {
    const canvas = ref<HTMLCanvasElement | null>(null);
    const context = ref<CanvasRenderingContext2D | null>(null);
    const fireworks = ref<Firework[]>([]);

    const resizeCanvas = () => {
      if (canvas.value) {
        canvas.value.width = window.innerWidth;
        canvas.value.height = window.innerHeight;
      }
    };

    onMounted(() => {
      if (canvas.value) {
        context.value = canvas.value.getContext('2d');
        resizeCanvas();
        window.addEventListener('resize', resizeCanvas);
        animate();
        setInterval(createRandomFirework, 1000); // 每秒创建一个随机烟花
      }
    });

    onBeforeUnmount(() => {
      window.removeEventListener('resize', resizeCanvas);
    });

    const createRandomFirework = () => {
      if (canvas.value) {
        const x = Math.random() * window.innerWidth;
        const y = Math.random() * window.innerHeight;
        fireworks.value.push(new Firework(x, y));
      }
    };

    const animate = () => {
      requestAnimationFrame(animate);
      if (context.value) {
        context.value.fillStyle = '#000';
        context.value.fillRect(0, 0, window.innerWidth, window.innerHeight);
        fireworks.value.forEach((firework, index) => {
          firework.update();
          firework.draw(context.value!);
          if (firework.isDone()) {
            fireworks.value.splice(index, 1);
          }
        });
      }
    };

    class Particle {
      constructor(public x: number, public y: number, public color: string) {
        this.radius = Math.random() * 2 + 1;
        this.speedX = Math.random() * 5 - 2.5;
        this.speedY = Math.random() * 5 - 2.5;
        this.alpha = 1;
      }

      radius: number;
      speedX: number;
      speedY: number;
      alpha: number;

      update() {
        this.x += this.speedX;
        this.y += this.speedY;
        this.alpha -= 0.01;
      }

      draw(ctx: CanvasRenderingContext2D) {
        ctx.save();
        ctx.globalAlpha = this.alpha;
        ctx.fillStyle = this.color;
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
        ctx.fill();
        ctx.restore();
      }

      isDone() {
        return this.alpha <= 0;
      }
    }

    class Firework {
      constructor(public x: number, public y: number) {
        this.particles = [];
        this.createParticles();
      }

      particles: Particle[];

      createParticles() {
        const colors = ['#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff', '#00ffff'];
        for (let i = 0; i < 100; i++) {
          const color = colors[Math.floor(Math.random() * colors.length)];
          this.particles.push(new Particle(this.x, this.y, color));
        }
      }

      update() {
        this.particles.forEach((particle) => particle.update());
      }

      draw(ctx: CanvasRenderingContext2D) {
        this.particles.forEach((particle) => particle.draw(ctx));
      }

      isDone() {
        return this.particles.every((particle) => particle.isDone());
      }
    }

    return {
      canvas,
    };
  },
});
</script>

<style scoped>
canvas {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
</style>
